package main

import (
	"fmt"
	"go_web/internal/global"
	"go_web/internal/repo/repo_sys"
	"go_web/internal/routes"
	"go_web/internal/task"
	cache_redis "go_web/pkg/cache"
	"go_web/pkg/config"
	"go_web/pkg/database"
	"go_web/pkg/middleware"
	"log"
	"os"
	"os/signal"
	"syscall"

	_ "go_web/api" // 引入生成 swagger.json 文件的位置

	"github.com/gin-gonic/gin"
	knife4goFiles "github.com/go-webtools/knife4go"
	knife4goGin "github.com/go-webtools/knife4go/gin"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
)

// @title Go Web API
// @version 1.0
// @description This is a sample server for Go Web API.
// @host localhost:9999
// @BasePath /api
func main() {
	defer func() {
		fmt.Println("停止 Cron 定时任务...")
		global.Cron.Stop()
	}()

	// 1. 初始化配置（复用已有的 config 模块）
	if err := config.Init(
		config.WithConfigDir("./configs"), // 配置文件目录（相对路径，基于项目根目录）
		config.WithEnv("dev"),             // 环境（可选）
	); err != nil {
		log.Fatalf("配置初始化失败：%v", err)
	}
	fmt.Println("✅ 配置模块初始化成功")

	// 2. 初始化数据库（依赖 config 模块的配置）
	if err := database.Init(); err != nil {
		log.Fatalf("数据库初始化失败：%v", err)
	}
	fmt.Println("✅ 数据库连接成功")

	repo_sys.SetDefault(global.DB) // 仓储层设置好 DB 数据库

	r := gin.Default()
	r.GET("/static/*filepath", middleware.StaticFileMiddleware(), func(c *gin.Context) {
		// 处理静态文件请求
		c.File("./static/" + c.Param("filepath"))
	})
	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
	r.GET("/knife4go/*any", knife4goGin.WrapHandler(knife4goFiles.Handler))
	routes.Init(r)
	go func() {
		if err := r.Run(":9999"); err != nil {
			log.Fatalf("服务启动失败: %v", err)
		}
	}()

	// 初始化 Redis
	cache_redis.Init()
	// 初始化 定时任务
	task.Init()

	for _, route := range r.Routes() {
		global.ReqUrls = append(global.ReqUrls, route.Path)
	}

	// 优雅退出（可选：捕获信号，关闭数据库连接）
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	fmt.Println("👋 程序开始退出...")

	// 关闭 Redis
	if err := global.Redis.Close(); err != nil {
		log.Printf("关闭 Redis 连接失败：%v", err)
	}

	// 关闭数据库连接
	if err := database.Close(); err != nil {
		log.Printf("关闭数据库连接失败：%v", err)
	}

	fmt.Println("✅ 程序退出完成")

}
